[Service Bus] Fix spurious DeliveryNotOnLinkException in session processor (#47356)#49603
Open
ksalazar-91 wants to merge 6 commits into
Open
Conversation
…essor (Azure#47356) A session-enabled ServiceBusProcessorClient that settles messages manually (e.g. complete()) while auto-complete is left enabled logged a spurious DeliveryNotOnLinkException ("...does not exist in the link's DeliveryMap") at ERROR. The V2 session disposition path (SessionsMessagePump) never called message.setIsSettled() on success, so the isSettled() guard could not absorb the redundant auto-settlement the way the non-session and V1 session paths do. The second disposition then reached the receive-link after the delivery had already been removed from the DeliveryMap, producing the error log. The message was always settled correctly on the broker; only the misleading ERROR log is removed. Now the session path marks the message settled on a successful disposition, mirroring ServiceBusReceiverAsyncClient, so a redundant settle short-circuits at the already-settled guard. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
|
Thank you for your contribution @ksalazar-91! We will review the pull request and get back to you soon. |
Contributor
There was a problem hiding this comment.
Pull request overview
This PR fixes a misleading DeliveryNotOnLinkException ERROR log that can occur in session-enabled ServiceBusProcessorClient when a message is settled manually inside the handler while auto-complete is still enabled, by ensuring the V2 session disposition path marks messages as settled after a successful disposition.
Changes:
- Mark
ServiceBusReceivedMessageas settled (message.setIsSettled()) after a successful disposition in the V2 session path to activate the existingmessage.isSettled()guard on redundant settlements. - Add a release note describing the removed spurious error log and clarifying that broker settlement was already succeeding.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| sdk/servicebus/azure-messaging-servicebus/src/main/java/com/azure/messaging/servicebus/SessionsMessagePump.java | Marks messages as settled on successful session disposition to prevent redundant settle attempts from reaching the receive-link. |
| sdk/servicebus/azure-messaging-servicebus/CHANGELOG.md | Documents the bug fix in 7.18.0-beta.2 (Unreleased) under “Bugs Fixed”. |
) Adds SessionsMessagePumpIsolatedTest#shouldNotReDispositionWhenHandlerSettlesWithAutoCompleteEnabled, covering the V2 session path where a handler settles a message manually while auto-complete is enabled. Verifies the message is marked settled and the redundant auto-settlement short-circuits at the isSettled() guard so the receive-link sees exactly one disposition (no second attempt that would raise DeliveryNotOnLinkException). Addresses the PR review feedback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
EldertGrootenboer
approved these changes
Jun 24, 2026
…hs (Azure#47356) Addresses PR review feedback: switch the session disposition success side-effect from doOnSuccess to .<Void>then(Mono.fromRunnable(() -> message.setIsSettled())), matching the pattern used by the non-session and V1 session paths in ServiceBusReceiverAsyncClient. Behavior is unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
EldertGrootenboer
approved these changes
Jun 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #47356.
A session-enabled
ServiceBusProcessorClient(PEEK_LOCK) that settles messages manually inside the handler — e.g. callingcontext.complete()— while auto-complete is left enabled (the default) intermittently logged a spurious error atERROR:The message is already settled correctly on the broker; the only symptom is this misleading
DeliveryNotOnLinkExceptionlog line (one per message). No messages are lost or redelivered, andprocessErroris not invoked.Root cause
The processor's auto-disposition feature settles a message after the handler returns. When the handler also settles manually, two dispositions are issued for the same delivery. The SDK is designed to absorb this redundant settle via the
message.isSettled()guard inupdateDisposition:The non-session and V1-session paths arm this guard by calling
message.setIsSettled()on a successful disposition (ServiceBusReceiverAsyncClient). The V2 session path (SessionsMessagePump.SessionReceiversTracker.updateDisposition) never did. So the flag stayedfalse, the guard could not trip, and the redundant auto-complete proceeded to a second link-level disposition on a delivery that had already been removed from theDeliveryMap— producing theDeliveryNotOnLinkExceptionERROR.Fix
Mark the message settled on a successful disposition in the V2 session path, mirroring the sibling paths:
This arms the existing
isSettled()guard so a redundant settle short-circuits with the benign "already settled" error (swallowed at verbose by the auto-disposition wrapper) instead of reaching the receive-link. The change is package-local toazure-messaging-servicebus; noazure-core-amqpchange is needed.Verification
Reproduced live against a Standard namespace with a session-enabled subscription, sending 5 messages to one session and a session processor that calls
complete()manually with auto-complete enabled.disableAutoComplete()The fix removes the error log with auto-complete still enabled (no customer config change required) and does not regress the manual-settlement path.
Notes for reviewers
disableAutoComplete()remains the recommended pattern when settling manually; this PR additionally makes the SDK fail quietly and consistently on a redundant settle for session processors, matching the documented "auto-settle is tolerated" behavior already present in the other receive paths.7.18.0-beta.2 (Unreleased)→ Bugs Fixed.